<template>
  <div>
    <h2 ref="msg">msg: {{msg}}</h2>
    <h2 ref="msg2">msg2: {{msg2}}</h2>
    <button @click="test">测试</button>
  </div>
</template>

<script>
/* 
理解nextTick
  当我们同步更新完数据后, DOM并不会立即更新, DOM是异步更新的
  问题: 当更新完数据后, 不能立即得到更新后的DOM
  解决: 使用nextTick来指定回调函数, 在回调中操作更新后的DOM, 前提是nextTick必须在数据更新后立即调用
什么是Tick:
  取出队列中的一个回调任务到调用栈中执行就是一个tick
  一个事件回调是一个Tick
  在一个事件回调中去更新数据和调用nextTick, 
  更新DOM的异步回调与nextTick指定的回调会放在一个大的异步任务中处理的
内部结构
  内部有一个callbacks用来存储在一个事件回调中nexTick指定的回调和更新DOM的回调  (内部维护的异步任务队列)
  内部有一个queue用来存储在一个事件回调中用于更新DOM的watcher, 那DOM更新的任务是一个整体的
  一旦更新了一个数据, 会立即将更新DOM的异步任务通过nextTick放入callbacks中
nextTick中用的是哪个异步技术呢?
  简单说: 优先使用微任务 => 宏任务
  详细说: promise => MutationObserver => setImmediate => setTimeout
*/
export default {
  name: 'NextTick',
  data () {
    return {
      msg: 'a',
      msg2: 'c'
    }
  },

  methods: {
    test () {
      this.msg2 = 'd' // 将更新DOM的异步任务通过nextTick放入callbacks中
      this.$nextTick(() => { // 异步回调 ==> 在DOM异步更新之后
        alert(this.$refs.msg.innerText) // 
      })
      this.msg = 'b'  // 后面会异步更新DOM, 也是在一个异步回调中执行
      // 不能立即读取到更新后的DOM
      // alert(this.$refs.msg.innerText)
      // 得等到DOM更新后, 再读取更新后的DOM
      this.$nextTick(() => { // 异步回调 ==> 在DOM异步更新之后
        alert(this.$refs.msg.innerText) // 
      })
      // this.msg += '---'
      // alert('更新数据之后')

      // 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法，
      // 获取更新后的 DOM。

      // callbacks: [watchers, nextTick1, nextTick2]
    }
  },

  watch: {
    msg (value) { 
      
    }
  }
}
</script>

<style scoped>

</style>
